import org.osflash.signals.Signal;

class Evt {
	public var value : String;

	public function new(v:String) {
		this.value = v;
	}
}

enum EVals {
	TNone;
	TInt(v:Int);
}

class Source {

	public var source0:Signal;
	public var sourceString:Signal;
	public var sourceInt:Signal;
	public var sourceMixed:Signal;
	public var sourceInstance : Signal;
	public var sourceEnum : Signal;
	public var sourceRepeat : Signal;

	public function new() {
		source0 = new Signal();
		sourceString = new Signal([String]);
		sourceInt = new Signal([Int]);
		sourceMixed = new Signal([String,Int,Float]);
		sourceInstance = new Signal([Evt]);
		sourceEnum = new Signal([EVals]);
		sourceRepeat = new Signal();
	}

	public function test() {
		var src = this;
		src.emit0();
		src.emitString();
		src.emitInt();
		src.emitMixed();
		src.emitInstance();
		src.emitEnum();

		src.emitRepeat();
		src.emitRepeat();
		src.emitRepeat();
	}

	public function emit0():Void {
		source0.dispatch();
	}

	public function emitString():Void {
		sourceString.dispatch(["Signal from emitString"]);
	}

	public function emitInt():Void {
		sourceInt.dispatch([1]);
	}

	public function emitMixed():Void {
		sourceMixed.dispatch(["Int and float next", 4, 5.5]);
	}

	public function emitInstance():Void {
		var e = new Evt("event info here");
		sourceInstance.dispatch([e]);
	}

	public function emitEnum():Void {
		var e = TNone;
		sourceEnum.dispatch([e]);
		e = TInt(5);
		sourceEnum.dispatch([e]);
	}

	function emitRepeat():Void {
		sourceRepeat.dispatch();
	}
}

class Simple {
	var src : Source;

	public function new() {
		src = new Source();

		registerListeners();
		src.test();
		trace("---- There should be no signals after here ----");
		unregisterListeners();
		src.test();
	}

	private function registerListeners() {
		src.source0.add(receive0);
		src.sourceString.add(receiveString);
		src.sourceInt.add(receiveInt);
		src.sourceMixed.add(receiveMixed);
		src.sourceInstance.add(receiveInstance);
		src.sourceEnum.add(receiveEnum);
		src.sourceRepeat.addOnce(receiveRepeatOnce);
		src.sourceRepeat.add(receiveRepeat);
	}

	private function unregisterListeners() {
		src.source0.remove(receive0);
		src.sourceString.remove(receiveString);
		src.sourceInt.remove(receiveInt);
		src.sourceMixed.remove(receiveMixed);
		src.sourceInstance.remove(receiveInstance);
		src.sourceEnum.remove(receiveEnum);
		src.sourceRepeat.remove(receiveRepeatOnce);
		src.sourceRepeat.remove(receiveRepeat);
	}

	private function receive0():Void {
		trace("receive0 signal");
	}

	private function receiveString(v:String):Void {
		trace("receiveString : " + v);
	}

	private function receiveInt(v:Int):Void {
		trace("receiveInt : " + v);
	}

	private function receiveMixed(a:String,b:Int,c:Float):Void {
		trace("receiveMixed : " + a +", " + b + ", "+ c);
	}

	private function receiveInstance(e:Evt) {
		trace("receiveInstance : " + e.value); 
	}

	private function receiveEnum(v:EVals) {
		trace("receiveEnum : " + Std.string(v));
	}

	private function receiveRepeatOnce() {
		trace("I should show once");
	}

	private function receiveRepeat() {
		trace("I should show three times");
	}

	public static function main() {
		var l = new Simple();
	}
}
